package com.huitong.common.mybatis.encrypt.encryptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.SM4;
import com.huitong.common.mybatis.enums.EncodeType;
import com.huitong.common.mybatis.properties.EncryptCustomProperties;

import java.nio.charset.StandardCharsets;

/**
 * SM4加密算法
 *
 * @author fromdrowning
 * @date 2024/4/13 9:49
 */
public class SM4Encryptor extends EncryptorTemplate {

    /**
     * 秘钥
     */
    private final String secretKey;

    /**
     * SM4加密算法
     *
     * @param encryptCustomProperties 敏感字段加密自定义配置
     */
    public SM4Encryptor(EncryptCustomProperties encryptCustomProperties) {
        super(encryptCustomProperties);
        this.secretKey = encryptCustomProperties.getSecretKey();
    }

    /**
     * 校验加密算法必要的参数配置
     */
    @Override
    public void verifyProperties() {
        if (StrUtil.isBlank(secretKey)) {
            throw new IllegalArgumentException("SM4加密需要传入秘钥信息");
        }
        if (16 != secretKey.length()) {
            throw new IllegalArgumentException("SM4加密秘钥长度要求为16位");
        }
    }

    /**
     * 加密
     *
     * @param value      需要加密的敏感字段值
     * @param encodeType 加密后的编码类型
     * @return 加密后的敏感字段值
     */
    @Override
    public String encrypt(String value, EncodeType encodeType) {
        SM4 sm4 = SmUtil.sm4(secretKey.getBytes(StandardCharsets.UTF_8));
        return encodeType == EncodeType.HEX ? sm4.encryptHex(value, StandardCharsets.UTF_8) :
            sm4.encryptBase64(value, StandardCharsets.UTF_8);
    }

    /**
     * 解密
     *
     * @param value 需要解密的敏感字段值
     * @return 解密后的敏感字段值
     */
    @Override
    public String decrypt(String value) {
        return SmUtil.sm4(secretKey.getBytes(StandardCharsets.UTF_8))
            .decryptStr(value, StandardCharsets.UTF_8);
    }
}
